package com.quan.wx.web.biz.controller.xczs;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSON;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.quan.base.common.base.web.support.BaseResult;
import com.quan.base.common.base.web.support.controller.BaseController;
import com.quan.base.common.exception.BizException;
import com.quan.base.common.utils.Paginator;
import com.quan.base.common.utils.RandomUitl;
import com.quan.base.common.utils.RegexUtils;
import com.quan.base.common.utils.sms.SmsUtils;
import com.quan.weixin.WeixinConstant;
import com.quan.weixin.common.WeixinContext;
import com.quan.weixin.rpc.api.WeixinQrCodeService;
import com.quan.weixin.rpc.model.WeixinQrCode;
import com.quan.weixin.tools.WeiXinTools;
import com.quan.xczs.rpc.api.XczsGoodsGroupGoodsService;
import com.quan.xczs.rpc.api.XczsGoodsGroupService;
import com.quan.xczs.rpc.api.XczsGoodsOrderService;
import com.quan.xczs.rpc.api.XczsUserInvitedService;
import com.quan.xczs.rpc.api.XczsUserService;
import com.quan.xczs.rpc.model.XczsGoodsOrder;
import com.quan.xczs.rpc.model.XczsUser;
import com.quan.xczs.rpc.model.XczsUserInvited;

@RestController
@RequestMapping(value = "/wx/xczs")
public class XczsBizController extends BaseController {
	
	@Autowired
	private XczsUserService xczsUserService ;
	
	@Autowired
	private XczsUserInvitedService xczsUserInvitedService ;

	@Autowired
	private WeixinQrCodeService weixinQrCodeService ;
	
	@Autowired
	private XczsGoodsGroupService xczsGoodsGroupService ;
	
	@Autowired
	private XczsGoodsGroupGoodsService xczsGoodsGroupGoodsService ;
	
	@Autowired
	private XczsGoodsOrderService xczsGoodsOrderService ;
	
	
	/**
	 * 用户调起支付窗口前，保存订单支付记录，又客户端传入
	 * @param entity
	 * @return
	 */
	@PostMapping(value = "/saveOrderPayInfo")
	public Object saveOrderPayInfo(XczsGoodsOrder entity) {
		try {
			this.xczsGoodsOrderService.insertSelective(entity) ;
		} catch (BizException e) {
			return BaseResult.failure() ;
		}
		return BaseResult.ok() ;
	}
	
	/**
	 * 获取所有学车套餐
	 * @return
	 */
	@GetMapping(value = "/getGoodsGroup")
	public Object getGoodsGroup() {
		return BaseResult.loadOk(this.xczsGoodsGroupService.selectAll()) ;
	}
	
	/**
	 * 根据ID获取套餐
	 * @param goodsGroupId
	 * @return
	 */
	@GetMapping(value = "/getGoodsGroupById")
	public Object getGoodsGroupById(Integer goodsGroupId) {
		return this.xczsGoodsGroupService.selectById(goodsGroupId) ;
	}
	
	/**
	 * 获取学车套餐关联的商品
	 * @param goodsGroupId
	 * @return
	 */
	@GetMapping(value = "/getGoods")
	public Object getGoods(Integer goodsGroupId) {
		return BaseResult.loadOk(this.xczsGoodsGroupGoodsService.selectGoods(goodsGroupId)) ;
	}
	
	/**
	 * 获取用户信息
	 * @param openid
	 * @return
	 */
	@GetMapping(value = "/getMyUserInfo")
	public Object getMyUserInfo(String openid, String mobile) {
		return this.xczsUserService.getUserByOpenId(openid) ;
	}
	
	/**
	 * 获取我的推荐人列表
	 * @param entity
	 * @param refereeOpenid
	 * @return
	 */
	@GetMapping(value = "/getMyInvitedList")
	public Object getMyInvitedList(String refereeOpenid, String mobile, String type) {
		return this.xczsUserInvitedService.selectMyInvitedByRefereeOpenid(new Paginator(request), refereeOpenid) ;
	}
	
	/**
	 * 用户非正常下进入注册页面，注册前验证该用户是否已注册过（绑定手机号），如果已注册过则跳转到业务页面
	 * @param openid
	 * @return
	 */
	@GetMapping(value = "/validRegister")
	public Object validRegister(String openid) {
		XczsUser userByOpenId = this.xczsUserService.getUserByOpenId(openid) ;
		if(null != userByOpenId && StringUtils.isNotBlank(userByOpenId.getMobile())) {
			return BaseResult.ok("用户已注册并绑定手机号");
		} else {
			return BaseResult.failure("用户为注册，可以注册") ;
		}
	}
	
	/**
	 * 我的二维码和邀请朋友生成的二维码
	 * @param openid 我的openid
	 * @param mobile 我的手机号码
	 * @return
	 */
	@PostMapping(value = "/getMyInviteQrCode")
	public Object register(String openid, String mobile) {
		logger.debug("生成临时二维码----------------------");
		
		Map<String, Object> sceneMap = new HashMap<String, Object>() ;
		sceneMap.put("type", "invite"); //扫描带参数事件，type用于区分是否扫描邀请
		sceneMap.put("openid", openid);
		sceneMap.put("mobile", mobile);
		String sceneValue = JSON.toJSONString(sceneMap) ;
		logger.debug("临时二维码场景值：{}", sceneValue);
		
		String showQRCodeTemp = WeiXinTools.showQRCodeTemp(WeixinContext.getAccessToken(), WeixinConstant.QR_CODE_EXPIRE_SECONDS, sceneValue) ;
		
		//记录二维码生成数据
		WeixinQrCode entity = new WeixinQrCode() ;
		entity.setQrCodeType(1);
		entity.setOpenid(openid);
		entity.setSceneValue(sceneValue);
		entity.setQrCodeUrl(showQRCodeTemp);
		entity.setExpireSeconds(WeixinConstant.QR_CODE_EXPIRE_SECONDS);
		entity.setComputerExpireSeconds((entity.getExpireSeconds() * 1000) + System.currentTimeMillis());
		this.weixinQrCodeService.insertSelective(entity);
		
		if(StringUtils.isNotBlank(showQRCodeTemp)) {
			return BaseResult.ok(showQRCodeTemp) ;
		} else {
			return BaseResult.failure("生成二维码失败") ;
		}
	}
	
	/**
	 * 学车招生-用户注册获取短信验证码
	 * @param mobile 手机号
	 * @return
	 */
	@PostMapping(value = "/getValidCode")
	public Object getValidCode(String openid, String mobile) {
		if(StringUtils.isBlank(mobile)) {
			return BaseResult.failure("手机号不能为空");
		}
		if(!RegexUtils.isPhoneNumber(mobile)) {
			return BaseResult.failure("手机号格式不正确");
		}
		
		XczsUser checkValue = this.xczsUserService.checkValue("mobile", mobile) ;
		if(null != checkValue && null != checkValue.getId()) {
			return BaseResult.failure("该号码已注册");
		}
		
		//1、生成验证码
		String validCode = RandomUitl.generateInteger(4) ;
		
		//2、发送短信
		try {
			SendSmsResponse response = SmsUtils.sendSms(mobile, "杨浩泉", "SMS_126971378", "{\"code\":\""+validCode+"\"}") ;
			if(response.getCode().equals("OK")) {
				logger.debug("获取验证码，短信发送成功===>手机号：{}, 验证码：{}, OPENDID：{}", mobile, validCode, openid);
				
				//3、短信发送成功，保存短信验证码到数据库
				int registerSetValidCode = this.xczsUserService.registerSetValidCode(openid, validCode, 30);
				
				if(registerSetValidCode > 0) {
					return BaseResult.ok("短信已发送");
				} else {
					logger.error("短信已发送，但保存验证码到数据库失败");
					return BaseResult.failure("短信发送失败");
				}
			} else {
				System.out.println(response.getCode());
				logger.debug("获取验证码，短信发送失败===>手机号：{}, 验证码：{}, OPENDID：{}, 错误信息：{}", mobile, validCode, openid, response.getMessage());
				if("isv.BUSINESS_LIMIT_CONTROL".equals(response.getCode())) {
					return BaseResult.failure("短信发送过于频繁，请稍后再试");
				} else {
					return BaseResult.failure("短信发送失败");
				}
			}
		} catch (ClientException e) {
			logger.error("短信发送异常：{}", e.getMessage());
		}
		
		return BaseResult.failure("短信发送失败");
	}
	
	/**
	 * 学车招生-用户注册获取短信验证码
	 * @param openid 微信用户openid
	 * @param mobile 手机号
	 * @param validCode 验证码
	 * @param realName 真实姓名
	 * @param state 识别参数，用于识当前注册用户是否以被邀请的方式注册（邀请参数：invite）
	 * @param refereeOpenid 推荐人openid
	 * @return
	 */
	@PostMapping(value = "/register")
	public Object register(String openid, String mobile, String validCode, String realName, String state, String refereeOpenid) {
		if(StringUtils.isBlank(mobile)) {
			return BaseResult.failure("手机号不能为空");
		}
		if(StringUtils.isBlank(validCode)) {
			return BaseResult.failure("验证码不能为空");
		}
		if(StringUtils.isBlank(realName)) {
			return BaseResult.failure("姓名不能为空");
		}
		
		logger.debug("用户注册===>手机号：{}, 验证码：{}, 真实姓名：{}", mobile, validCode, realName);
		
		try {
			XczsUser userByOpenId = this.xczsUserService.getUserByOpenId(openid) ;
			if(null != userByOpenId) {
				//1、比对用户提交的验证码
				if(!userByOpenId.getValidCode().equals(validCode)) {
					return BaseResult.failure("验证码不正确");
				}
				//2、判断验证码是否过期
				if(System.currentTimeMillis() > userByOpenId.getValidCodeExpire()) {
					return BaseResult.failure("验证码已过期，请重新获取");
				}
				
				if(StringUtils.isNotBlank(state) && state.equals("invite")) {
					logger.debug("注册方式==>被邀请注册");
					logger.debug("推荐人OPENID==>{}", refereeOpenid);
					logger.debug("被邀请人OPENID==>{}", openid);
					
					XczsUserInvited invited = new XczsUserInvited() ;
					invited.setRefereeOpenid(refereeOpenid);
					invited.setInvitedOpenid(openid);
					invited.setInvitedMobile(mobile);
					
					this.xczsUserService.registerBinding(openid, realName, mobile, invited) ;
					
					logger.debug("注册成功，跳转至业务页面");
				} else {
					logger.debug("注册方式==>主动注册");
					this.xczsUserService.registerBinding(openid, realName, mobile) ;
					logger.debug("注册成功，跳转至业务页面");
				}
				
				return BaseResult.ok("注册成功") ;
				
			} else {
				logger.error("用户注册失败，无法根据OPENID获取用户信息");
				return BaseResult.failure("注册失败");
			}
		} catch (Exception e) {
			if(StringUtils.isNotBlank(state) && state.equals("invite")) {
				logger.error("被邀请注册失败：{}", e.getMessage());
			} else {
				logger.error("主动注册失败：{}", e);
			}
			return BaseResult.failure("注册失败，系统错误") ;
		}
	}
	
}
